﻿//using JWT.Algorithms;
//using JWT.Builder;
//using JWT.Exceptions;
using learun.util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;

using IdentityModel;
using System.IdentityModel.Tokens.Jwt;

using Microsoft.IdentityModel.Tokens;
using System.Text;
//using Microsoft.IdentityModel.Tokens;
//using System.IdentityModel.Tokens.Jwt;

namespace Productive.Assets
{
    public class Operator : IOperator
    {
        //private readonly ICache _cache;
        //public Operator(ICache cache) {
        //    _cache = cache;
        //}
        ///// <summary>
        ///// 判断是否登录
        ///// </summary>
        ///// <param name="account">账号</param>
        ///// <param name="token">token</param>
        ///// <returns></returns>
        //public async Task<bool> IsOnLine(string account,string token)
        //{
        //    try
        //    {
        //        string accountTmp = await _cache.ReadAsync<string>(token);

        //        if (account == accountTmp)
        //        {
        //            return true;
        //        }
        //        else {
        //            return false;
        //        }
        //    }
        //    catch (Exception)
        //    {
        //        return false;
        //    }
        //}
        ///// <summary>
        ///// 添加登录者(保存一天时间)
        ///// </summary>
        ///// <param name="account">账号</param>
        ///// <returns></returns>
        //public async Task<string> AddLoginUser(string account) {
        //    string token = Guid.NewGuid().ToString();
        //    TimeSpan ts = new TimeSpan(1, 0, 0, 0);
        //    var list = await _cache.ReadAsync<List<string>>(account);
        //    if (list == null) {
        //        list = new List<string>();
        //    }
        //    list.Add(token);
        //    await _cache.WriteAsync(account, list, ts);
        //    await _cache.WriteAsync(token, account, ts);
        //    return token;
        //}

        ///// <summary>
        ///// 清除登录者信息
        ///// </summary>
        ///// <param name="account">登录者用户账号</param>
        ///// <returns></returns>
        //public async Task ClearLoginUser(string account)
        //{
        //    var list = await _cache.ReadAsync<List<string>>(account);
        //    if (list != null)
        //    {
        //        foreach (var token in list)
        //        {
        //            await _cache.RemoveAsync(token);
        //        }
        //        await _cache.RemoveAsync(account);
        //    }
        //}


        /// <summary>
        /// 颁发JWT字符串
        /// </summary>
        /// <param name="tokenModel"></param>
        /// <param name="jwtConfig"></param>
        /// <returns></returns>
        public string EncodeToken(string userId, string userName, string account, JWTConfig jwtConfig)
        {
            var dateTime = DateTime.Now;//UtcNow
            var claims = new Claim[]
            {
                //https://blog.csdn.net/ahilll/article/details/83821853
                //new Claim(JwtClaimTypes.Audience,jwtConfig.Audience),
                //new Claim(JwtClaimTypes.Issuer,jwtConfig.Issuer),

                new Claim("UserId", userId),//用户Id
                new Claim("UserName", userName),//用户userName
                new Claim("Account", account),//用户userName


                //.AddClaim("UserId", userId).AddClaim("UserName", userName).AddClaim("Account", account)
                //new Claim(ClaimTypes.Name, tokenModel.Uname.ToString()), 
                //这个Role是官方UseAuthentication要要验证的Role，我们就不用手动设置Role这个属性了
                //new Claim(ClaimTypes.Role, tokenModel.Role),//角色 要用ClaimTypes.Role 否则[Authorize("admin")]不起作用
                //new Claim("Project", tokenModel.Project),//角色
                //new Claim("Type", tokenModel.Type),//身份类型，角色类型
                //new Claim("ClasssId", Convert.ToString(tokenModel.ClasssId)),//班级编号
                //new Claim("SchoolId", Convert.ToString(tokenModel.SchoolId)),//学校编号


                //时间
                //new Claim(JwtRegisteredClaimNames.Iat,dateTime.ToString(),ClaimValueTypes.Integer64)
            };
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtConfig.JwtSecret));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            //过期时间
            double exp = jwtConfig.JwtExp;
            //switch (tokenModel.TokenType)
            //{
            //    case TokenType.Web:
            //        exp = jwtConfig.WebExp;
            //        break;
            //    case TokenType.App:
            //        exp = jwtConfig.AppExp;
            //        break;
            //    case TokenType.MiniProgram:
            //        exp = jwtConfig.MiniProgramExp;
            //        break;
            //    case TokenType.Other:
            //        exp = jwtConfig.OtherExp;
            //        break;
            //    default:
            //        exp = jwtConfig.AppExp;
            //        break;
            //}
            var jwt = new JwtSecurityToken(
                
                issuer: jwtConfig.Issuer,
                audience: jwtConfig.Audience,

                claims: claims, //声明集合

                notBefore: dateTime,

                expires: dateTime.AddHours(exp),//时间
                signingCredentials: creds);

            var jwtHandler = new JwtSecurityTokenHandler();
            var encodedJwt = jwtHandler.WriteToken(jwt);

        
            return encodedJwt;
        }

        /// <summary>
        /// 解析
        /// </summary>
        /// <param name="jwtStr"></param>
        /// <returns></returns>
        public string DecodeToken(string jwtStr)
        {
            //NLogHelper.logger.Info($"序列化token:{jwtStr}");
            //Console.WriteLine($"序列化token:{jwtStr}");
            //var jwtHandler = new JwtSecurityTokenHandler();


            //var jwtHandler = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler();
            //JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(jwtStr);


            //object userId = new object();
            //object userName = new object(); ;
            //object account = new object(); ;
            //object project = new object();
            //object Type = new object();
            //object ClasssId = new object();
            //object SchoolId = new object();
            try
            {
                //jwtToken.Payload.TryGetValue(JwtClaimTypes.Id, out userId);
                //jwtToken.Payload.TryGetValue(ClaimTypes.Name, out userName);
                //jwtToken.Payload.TryGetValue(ClaimTypes.Role, out account);

                //jwtToken.Payload.TryGetValue("Project", out project);
                //jwtToken.Payload.TryGetValue("Type", out Type);
                //jwtToken.Payload.TryGetValue("ClasssId", out ClasssId);
                //jwtToken.Payload.TryGetValue("SchoolId", out SchoolId);
                var jwtHandler = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler();
                JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(jwtStr);

                return Newtonsoft.Json.JsonConvert.SerializeObject(jwtToken.Payload);
            }
            catch (Exception e)
            {
                return "TokenExpiredException";
            }
            //var tm = new Token
            //{
            //    Uid = Convert.ToInt32(id),
            //    Uname = name.ToString(),
            //    Role = Convert.ToString(role),
            //    Project = Convert.ToString(project),
            //    Type = Convert.ToString(Type),
            //    ClasssId = Convert.ToInt32(ClasssId),
            //    SchoolId = Convert.ToInt32(SchoolId)
            //};
            return "";
        }


        /// <summary>
        /// 生成jwt令牌
        /// </summary>
        /// <param name="userId">用户id</param>
        /// <param name="userName">用户名称</param>
        /// <param name="account">用户账号</param>
        /// <returns></returns>
        //public string EncodeToken(string userId, string userName, string account)
        //{
        //    var token = new JwtBuilder()
        //    .WithAlgorithm(new HMACSHA256Algorithm())
        //    .WithSecret(ConfigHelper.GetConfig().JwtSecret)
        //    .AddClaim("iat", DateTimeOffset.UtcNow.ToUnixTimeSeconds())
        //    .AddClaim("exp", DateTimeOffset.UtcNow.AddHours(12).ToUnixTimeSeconds()) // 设置12小时过期
        //    .AddClaim("UserId", userId).AddClaim("UserName", userName).AddClaim("Account", account)
        //    .Encode();

        //    return token;
        //}
        /// <summary>
        /// 解密jwt令牌
        /// </summary>
        /// <param name="token">令牌</param>
        /// <returns>TokenExpiredException 时间过期,SignatureVerificationException 签证不正确</returns>
        //public string DecodeToken(string token)
        //{
        //    try
        //    {
        //        var json = new JwtBuilder()
        //            .WithAlgorithm(new HMACSHA256Algorithm())
        //            .WithSecret(ConfigHelper.GetConfig().JwtSecret)
        //            .MustVerifySignature()
        //            .Decode(token);
        //        return json;
        //        //Console.WriteLine(json);
        //    }
        //    catch (TokenExpiredException)
        //    {
        //        return "TokenExpiredException";
        //        //Console.WriteLine("Token has expired");
        //    }
        //    catch (SignatureVerificationException)
        //    {
        //        return "SignatureVerificationException";
        //        //Console.WriteLine("Token has invalid signature");
        //    }
        //}
    }
}
